import string

from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
import time
from bs4 import BeautifulSoup
import xlwt
import xlrd
import math


# 判断字符串是否包含中文
def is_chinese(check_str):
    for ch in check_str:
        if u'\u4e00' <= ch <= u'\u9fff':
            return True
    return False


def get_rows():
    try:
        # excel路径
        excle_path = r'D:/tuniu-HInfos.xls'
        # 打开excel读取文件
        data = xlrd.open_workbook(excle_path)
        # 根据sheet下标选择读取内容
        sheet = data.sheet_by_index(0)
        # 获取到表的总行数
        nrows = sheet.nrows - 3
    except FileNotFoundError:
        nrows = 0
    return nrows


class QunarSpider():
    def theSpider(self, city, startdate, enddate):
        chrome_options = Options()
        chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9221")
        driver = webdriver.Chrome(options=chrome_options)
        print(driver.title)
        homeUrl = 'https://hotel.tuniu.com/';
        driver.get(homeUrl)
        # 选取城市
        toCity = driver.find_element_by_xpath("//input[@data-id='city-input']")
        toCity.clear()
        toCity.send_keys(city)
        # element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, "hot_key_list")))
        toCity.send_keys(Keys.TAB)
        time.sleep(2)
        # # 选取结束日期
        # checkOutDate = driver.find_element_by_xpath("//div[@class='check-out']")
        # checkOutDate.click()
        # # 键盘全选操作,ctrl+A
        # checkOutDate.send_keys(Keys.CONTROL, "a")
        # checkOutDate.send_keys(Keys.DELETE)
        # checkOutDate.send_keys(enddate)
        #
        # # 选取开始日期
        # checkInDate = driver.find_element_by_xpath("//div[@class='check-in']")
        # checkInDate.click()
        # # 键盘全选操作,ctrl+A
        # checkInDate.send_keys(Keys.CONTROL, "a")
        # checkInDate.send_keys(Keys.DELETE)
        # checkInDate.send_keys(startdate)

        # 进行搜索
        search = driver.find_element_by_xpath("//div[@class='search-btn']")
        search.click()
        time.sleep(5)

        handle2 = driver.current_window_handle
        # 页面解析，并创建数据列表
        # 酒店序号
        handles2 = driver.window_handles
        for newHandle2 in handles2:
            if newHandle2 != handle2:
                driver.switch_to.window(newHandle2)
            else:
                driver.switch_to.window(newHandle2)
                driver.close()
        num = 1
        page_num = 1
        html = driver.page_source
        soup = BeautifulSoup(html, "html.parser")
        containtotalNumStr = str(soup.find('div', class_="hotel-count f-s").text)
        totalNum = int(containtotalNumStr[4:containtotalNumStr.index('家')])
        totalPageNum = math.ceil(totalNum / 10)
        contentList = []
        handle = driver.current_window_handle
        try:
            for l in range(0, totalPageNum):
                print('跑到第 ' + str(int(l + 1)) + ' 页')
                time.sleep(10)
                items = driver.find_elements_by_xpath("//img[@class='hotel-pic']")
                for item in items:
                    # item.click()
                    ActionChains(driver).move_to_element(item).click().perform()
                    handles = driver.window_handles
                    time.sleep(5)
                    for newHandle in handles:
                        if newHandle != handle:
                            driver.switch_to.window(newHandle)
                            try:
                                name = driver.find_element_by_xpath("//div[@class='hotel-name f-s']").text
                                htmlNew = driver.page_source
                                soupNew = BeautifulSoup(htmlNew, "html.parser")
                                # 获取指定class属性的的div标签数
                                lens = len(soupNew.find('div', class_="item mt10 instruction-block").select('div p')) - 1
                                # 获取指定class属性的div标签中最后一个标签的文本内容，并截取文本内容
                                phone = str(soupNew.find('div', class_="item mt10 instruction-block").select('div p')[lens].text)[5:]
                                if is_chinese(phone):
                                    phone = str(soupNew.find('div', class_="item mt10 instruction-block").select('div p')[lens - 1].text)[5:]
                                    if is_chinese(phone):
                                        phone = ''
                            except:
                                time.sleep(30)
                                phone = ''
                                print("exception", name, phone)
                            finally:
                                driver.switch_to.window(newHandle)
                                driver.close()
                    driver.switch_to.window(handle)
                    print(name, "——————————", phone)
                    contentSgl = [num, name, phone, startdate, enddate]
                    contentList.append(contentSgl)
                    num += 1
                # 解析多页
                time.sleep(5)
                try:
                    # 获取下一页的按钮标签
                    nextPage = driver.find_element_by_xpath("//li[@class='arrowR']")
                except:
                    print("发生异常，请检查代码逻辑是否正常")
                # nextPage.click()
                try:
                    # 点击调整到下一页
                    ActionChains(driver).move_to_element(nextPage).click().perform()
                except StaleElementReferenceException:
                    print("发生异常，重新加载一遍")
                    ActionChains(driver).move_to_element(nextPage).click().perform()
        finally:
            time.sleep(5)
            page_num += 1

            # 创建Excel表，并写入数据
            # 创建Excel表
            f = xlwt.Workbook()
            # 创建一个sheet对象，命名为“酒店信息”，cell_overwrite_ok表示是否可以覆盖单元格，是Worksheet实例化的一个参数，默认值是False
            sheet1 = f.add_sheet('酒店信息', cell_overwrite_ok=False)
            # 标题信息行列表
            rowTitle = ['序号', '酒店名称', '电话号码', '入住如期', '离店日期']
            # 遍历写入标题行信息
            for i in range(0, len(rowTitle)):
                # 其中的'0'表示行, 'i'表示列，0和i指定了表中的单元格，'rowTitle[i]'是向该单元格写入的内容
                sheet1.write(0, i, rowTitle[i])
            # 遍历写入数据信息
            # 先遍历一下有多少行
            for k in range(0, len(contentList)):
                # 再把每行的每个单元格遍历一下，j表示列数据
                for j in range(0, len(contentList[k])):
                    # k+1表示先去掉标题行，j表示列数据，contentList[k][j] 插入单元格数据
                    sheet1.write(k + 1, j, contentList[k][j])
            f.save('D:/tuniu-HInfos.xls')


if __name__ == '__main__':
    spider = QunarSpider()
    # city = input("请输入城市：")
    # startdate = input("请输入入住日期（yyyy-mm-dd):")
    # enddate = input("请输入离店日期（yyyy-mm-dd):")
    # totalpagenum = input("请输入爬取页数：")
    print("正在爬取中...")
    # spider.theSpider(city, startdate, enddate,totalpagenum)
    spider.theSpider('北京', '2021-02-20', '2021-02-24')

    # containtotalNumStr = '酒店电话：010-63157778'
    # print(containtotalNumStr[0])
    # #print(str(containtotalNumStr.index('家')))
    # print(containtotalNumStr[5:])
